Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustvmm_gen: Introduce rustvmm_gen #177

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

RuoqingHe
Copy link
Contributor

Summary of the PR

  • rustvmm_gen: Introduce lib_kernel_source.py
  • rustvmm_gen: Introduce lib_syscall.py
  • rustvmm_gen: Introduce rustvmm_gen

rustvmm_gen.py integrates kernel version checking, source extraction, compilation and header installation. Header files could be prepared with command:

./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> prepare

Source code required by seccompiler could be generated with command:

./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> generate_syscall

Requirements

Before submitting your PR, please make sure you addressed the following
requirements:

  • All commits in this PR have Signed-Off-By trailers (with
    git commit -s), and the commit message has max 60 characters for the
    summary and max 75 characters for each description line.
  • All added/changed functionality has a corresponding unit/integration
    test.
  • All added/changed public-facing functionality has entries in the "Upcoming
    Release" section of CHANGELOG.md (if no such section exists, please create one).
  • Any newly added unsafe code is properly documented.

Copy link
Collaborator

@roypat roypat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool idea! I like having some centralized tools for dealing with all the bindings generation for our various crates. I do think the seccompiler-specific part should go into rust-vmm/seccompiler, however. What I'd find really useful would be to have some wrapper around bindgen-rs that can be used to generate the bindings in crates like linux-loader and kvm-bindings (and I maybe xen-sys?) as well, built on top of the kernel header fetching you included here. Do you think that's a possible extension? :o

As a high level comment, maybe let's rename rustvmm_gen/ to just be scripts/, or tools/, and drop the lib_ prefix from the library files, instead moving them to some lib subdirectory.

Comment on lines 50 to 60
def create_temp_dir(version):
temp_dir = os.path.join("/tmp", f"linux-{version}-prepare")

if os.path.exists(temp_dir):
shutil.rmtree(temp_dir)

try:
os.makedirs(temp_dir)
return temp_dir
except OSError as e:
raise RuntimeError(f"Failed to create temp directory: {e}") from e
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use something that relies on mkdtemp(2) here to avoid race conditions and the "delete if exists" dance: https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory

"""
# Validate version format
if not re.match(r"^\d+\.\d+(\.\d+)?$", version):
return (False, "Invalid version format. Use X.Y or X.Y.Z")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this tuple of string and bool instead of just raising exceptions for errors, and returning void?



def install_headers(src_dir, arch, install_path, cleanup=False):
os.chdir(src_dir)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never chdirs back. Maybe with contextlib.chdir(src_dir):?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, changed to make -C instead

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script is specific to rust-vmm/seccompiler, right? If so it should probably live in that repository

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that lib file is specific to seccompiler, and I'm going to write according lib file for kvm-bindings and linux-loader, all of them are going to need installed headers to continue, WDYT 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generic parts, like downloading linux sources and installing headers, can live in rust-vmm-ci, and then there can be scripts in kvm-bindings/linux-leader/seccompiler that each call into the generic rust-vmm-ci scripts.

For kvm-bindings and linux-loader in particular there's probably some more common parts that can be moved into this repository (I was hoping some script that takes some .h files as input and produces .rs bindings from them?)

Copy link
Contributor Author

@RuoqingHe RuoqingHe Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have the required headers, for kvm-bindings and linux-loader we are only one step away which is a invocation of bindgen, and modify something (like for serde support), IMO that's similar to seccompiler while seccompiler doesn't need bindgen

print(f"Cleaning temporary files at {parent_dir}")
shutil.rmtree(parent_dir)

return True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also just drop the boolean return value here and simply raise an exception in the failure case

stderr=subprocess.STDOUT,
text=True,
)
print(result.stdout)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we just print result.stdout anyway, why not stdout=subprocess.PIPE above?

Comment on lines 53 to 55
except Exception as e:
print(f"\nError: {str(e)}")
exit(1)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really a need for this try-catch + exit, I think. The call to this function is the final statement in main(), so we hit an exception we'd exit with non-zero code anyway (and additionally printing "Error:" doesn't really add much imo), so can just drop this.

@RuoqingHe
Copy link
Contributor Author

Sorry I forget to mark this as a draft, kvm-bindings generation is on its way 😂

Thanks @roypat for reviewing! ❤️

@RuoqingHe RuoqingHe marked this pull request as draft February 17, 2025 11:11
@roypat
Copy link
Collaborator

roypat commented Feb 17, 2025

Sorry I forget to mark this as a draft, kvm-bindings generation is on its way 😂

Thanks @roypat for reviewing! ❤️

Ahahhaah, so sorry for jumping the gun! Looking forward to it then :D

`kernel_source.py` contains functions used to check version of desired
kernel, download, extract kernel source to specific directory and get
the headers out of it.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
`syscall.py` contains functions used to extract `syscall_table` from
headers installed by `kernel_source.py` and generate according Rust code
for specific architecture.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Add `__init__.py` for python programs outside `lib` to reference
functions inside lib.

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
`rustvmm_gen.py` integrates kernel version checking, source extraction,
compilation and header installation. Header files could be prepared with
command:

```command
./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> prepare
```

Source code required by `seccompiler` could be generated with command:

```command
./rustvmm_gen/rustvmm_gen.py --arch <arm64/x86_64/riscv> --version <X.Y/X.Y.Z> generate_syscall
```

Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants